package com.tuyrt.hi.navigation

import android.content.ComponentName
import android.content.Context
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.navigation.ActivityNavigator
import androidx.navigation.NavController
import androidx.navigation.NavGraph
import androidx.navigation.NavGraphNavigator
import androidx.navigation.fragment.DialogFragmentNavigator
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.TypeReference
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.tuyrt.hi.navigation.model.BottomBar
import com.tuyrt.hi.navigation.model.Destination
import java.io.BufferedReader
import java.io.InputStreamReader

/**
 * author: Administrator on 2021/6/7.
 * desc:
 */
object NavUtil {

    private var destinations: HashMap<String, Destination>? = null

    fun parseFile(context: Context, fileName: String): String {
        val input = context.assets.open(fileName)
        val stringBuilder = StringBuilder()
        BufferedReader(InputStreamReader(input)).use {
            var line: String
            while (true) {
                line = it.readLine() ?: break
                stringBuilder.append(line)
            }
        }
        return stringBuilder.toString()
    }

    fun getDestination(context: Context): HashMap<String, Destination> {
        val content = parseFile(context, "destination.json")
        return JSON.parseObject(content, object : TypeReference<HashMap<String, Destination>>() {}.type) as HashMap<String, Destination>
    }

    /**
     *  添加自定义 navigator到 navigatorProvider 中，然后遍历集合，
     *  根据destType类型从 navigatorProvider中取出对应的navigator，
     *  然后创建 node节点，设置id和className，把node节点添加到navGph对象中，
     *  在通过绑定 navController 和 navGraph
     */
    fun builderNavGraph(activity: FragmentActivity, childFm: FragmentManager, controller: NavController, containerId: Int) {
        val content = parseFile(activity, "destination.json")
        destinations = JSON.parseObject(content, object : TypeReference<HashMap<String, Destination>>() {}.type)
        destinations?.let {
            val iterator = it.values.iterator()
            val provider = controller.navigatorProvider

            val graphNavigator = provider.getNavigator(NavGraphNavigator::class.java)
            val navGraph = NavGraph(graphNavigator)

            val hiFragmentNavigator = HiFragmentNavigator(activity, childFm, containerId)
            provider.addNavigator(hiFragmentNavigator)

            while (iterator.hasNext()) {
                val destination = iterator.next()
                if ("activity" == destination.destType) {
                    val navigator = provider.getNavigator(ActivityNavigator::class.java)
                    val node = navigator.createDestination()
                    node.id = destination.id
                    node.setComponentName(ComponentName(activity.packageName, destination.clazzName))
                    navGraph.addDestination(node)
                } else if ("fragment" == destination.destType) {
                    // val navigator = provider.getNavigator(FragmentNavigator::class.java)
                    // val node = navigator.createDestination()
                    val node = hiFragmentNavigator.createDestination()
                    node.id = destination.id
                    node.className = destination.clazzName
                    navGraph.addDestination(node)
                } else if ("dialog" == destination.destType) {
                    val navigator = provider.getNavigator(DialogFragmentNavigator::class.java)
                    val node = navigator.createDestination()
                    node.id = destination.id
                    node.className = destination.clazzName

                    navGraph.addDestination(node)
                }

                if (destination.asStarter) {
                    navGraph.startDestination = destination.id
                }
            }
            controller.graph = navGraph
        }
    }

    fun buildBottomBar(navView: BottomNavigationView) {
        val content = parseFile(navView.context, "main_tabs_config.json")
        val bottomBar = JSON.parseObject(content, BottomBar::class.java)

        val tabs = bottomBar.tabs
        val menu = navView.menu
        for (tab in tabs) {
            if (!tab.enable) continue
            val destination = destinations?.get(tab.pageUrl)
            if (destination != null) {
                val menuItem = menu.add(0, destination.id, tab.index, tab.title)
                menuItem.setIcon(R.drawable.ic_home_black_24dp)
            }
        }
    }

}